'''如何自定义一个list方法'''

'''----index 0 data------index 1 data------index 2 data-----index 3 data----index 4 none'''
__all__ = ['Link','list']

class Node:
    def __init__(self):
        self.data = None
        self.next = None
        self.prev = None
class Link:
    def __init__(self,data=()):
        self.head = Node()
        self.tail = self.head
        self.length = 0
        for d in data:
            self.append(d)
    def __find_node(self, pos):
        nodeptr = self.head
        while pos:
            nodeptr = nodeptr.next
            pos -= 1
        return nodeptr #通过循环次数找到pos对应的节点位置

    def append(self,data):
        node = Node()   #首先生成新节点
        node.data = data #给节点赋值
        self.tail.next = node  #让tail的指针指向 新节点
        node.prev = self.tail #让tail成为新街点的前置位

        self.tail = node   #把tail对应新节点
        self.length += 1

    def pop(self, i=-1):
        if len(self) == 0:
            raise Exception('list is empty')
        if i == -1: #默认取最后一位
            node = self.tail #节点位于tail
            self.tail = node.prev #tail指向节点的前置位
            self.tail.next = None  #把tail的后置位指向为空
            self.length -= 1

            return node.data #返回data
        else:
            node = self.__find_node(i) #找到要删除的前一节点
            cur_node = node.next #表明要删除的位置
            third_node = node.next.next  #表明删除后的下一节点
            if third_node is not None:
                third_node.prev = node  #删除后的节点应该指向删除的前一节点
            node.next = third_node  #删除的前一节点指向后裔节点
            self.length -= 1
            return cur_node.data

    def insert(self,i,data):
        assert i <= len(self) - 1
        nodeptr = self.head
        while i:
            nodeptr = nodeptr.next  #去的要插入节点的前一节点
            i -= 1

        third_node = nodeptr.next #指明要插入的后一节点
        node = Node()  #创建新的节点
        node.data = data

        node.next = third_node #新节点的下一个指向后一节点
        third_node.prev = node

        nodeptr.next = node
        node.prev = nodeptr  #新节点的前一节点指向前一节点
        self.length += 1

    def remove(self,i):
        assert i <= len(self) - 1
        nodeptr = self.__find_node(i) #查找删除前一节点
        third_node = nodeptr.next.next #指明删除后一节点
        nodeptr.next = third_node  #把前一节点下一个指向后一节点
        third_node.prev = nodeptr #把后一节点指向前一节点，从而实现删除要删除的节点
        self.length -= 1

    def __len__(self):
        return self.length  #list的长度


    def __iter__(self): #返回一个可迭代对象
        return LinkIterator(self)

    def __setitem__(self, key, value):  #更新元素
        raise NotImplementedError

    def __getitem__(self, item):  #取值
        assert item <= len(self) - 1
        nodeptr = self.head.next
        while item:
            nodeptr = nodeptr.next
            item -= 1

        return nodeptr.data

    def __contains__(self, item): #contain方法确定list是否包换某个元素
        for d in self:
            if d == item:
                return True
        return False

    def __add__(self, other):
        l = Link()
        try:
            for i in self:
                l.append(i)
            for i in other:
                l.append(i)
        except:
            raise TypeError



class LinkIterator: #一个迭代生成器
    def __init__(self, link):
        self._node_ptr = link.head

    def __next__(self):
        self._node_ptr = self._node_ptr.next
        if self._node_ptr is None:
            raise StopIteration  #如果为空，停止迭代
        data = self._node_ptr.data
        return data

list = Link

# x = list.append(1)
#
# for d in x:
#     print(x)